﻿/*
Copyright © 2010 François Karman

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.

See <license.txt> for the complete license of the software.
*/

using System;
using System.Windows.Input;

namespace Faz.Dependencies
{
    /// <summary>
    /// Represents a command part of the WPF interface.
    /// </summary>
    public class CommandPresenter : ICommand
    {
        /// <summary>
        /// The method associated with the logic of the command.
        /// </summary>
        private readonly Action<ICommand, object> execute;

        /// <summary>
        /// The method associated with the activation of the command.
        /// </summary>
        private readonly Func<ICommand, object, bool> canExecute;

        /// <summary>
        /// Initializes a new instance of the CommandPresenter class.
        /// </summary>
        /// <param name="execute">
        /// The associated method called when the command is executed.
        /// </param>
        /// <param name="canExecute">
        /// A method that should return <c>true</c> when the command is
        /// active.
        /// </param>
        public CommandPresenter(Action<ICommand, object> execute, Func<ICommand, object, bool> canExecute)
        {
            this.execute = execute;
            this.canExecute = canExecute;
        }

        /// <summary>
        /// Initializes a new instance of the CommandPresenter class that is always active.
        /// </summary>
        /// <param name="execute">
        /// The associated method called when the command is executed.
        /// </param>
        public CommandPresenter(Action<ICommand, object> execute)
            : this(execute, null)
        {
        }

        /// <summary>
        /// Initializes a new instance of the CommandPresenter class that is always active.
        /// </summary>
        /// <param name="execute">
        /// The associated method called when the command is executed.
        /// </param>
        public CommandPresenter(Action execute)
            : this((i, p) => execute())
        {
        }

        /// <summary>
        /// Initializes a new instance of the CommandPresenter class that is always active.
        /// </summary>
        /// <param name="execute">
        /// The associated method called when the command is executed.
        /// </param>
        public CommandPresenter(Action<object> execute)
            : this((i, p) => execute(p))
        {
        }

        /// <summary>
        /// Occurs when changes occur that affect whether or not the command should execute.
        /// </summary>
        public event EventHandler CanExecuteChanged;

        /// <summary>
        /// Executes the associated method.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. If the command does not require data to be passed,
        /// this object can be set to <c>null</c>.
        /// </param>
        public void Execute(object parameter)
        {
            if (this.execute != null)
            {
                this.execute(this, parameter);
            }
        }

        /// <summary>
        /// Determines whether the command can execute in its current state.
        /// </summary>
        /// <param name="parameter">
        /// Data used by the command. If the command does not require data to be passed,
        /// this object can be set to <c>null</c>.
        /// </param>
        /// <returns>
        /// <c>true</c> if this command can be executed; otherwise, <c>false</c>.
        /// </returns>
        public bool CanExecute(object parameter)
        {
            if (this.canExecute != null)
            {
                return this.canExecute(this, parameter);
            }
            else
            {
                return true;
            }
        }
    }
}
